#include "RequestHandle.h"


RequestHandle::RequestHandle(void)
{
	m_nState = 0;
	m_DataPort = 0;
	memset(m_cSendBuf, 0, CustomBuf::SYNBUFSIZE + 1);
	memset(m_cServPath, 0, CustomBuf::SYNBUFSIZE + 1);
	m_pkDataRecv = new RecvLine();
}

RequestHandle::~RequestHandle(void)
{
}

void RequestHandle::SetState(int state)
{
	m_nState = state;
}

void RequestHandle::Close(void)
{
	closesocket(m_nConn);
}

void RequestHandle::SetFileName(char *fn, UINT len)
{
	strncpy_s(m_cFileName, fn, len);
}

void RequestHandle::HaveResponse(void)
{
	CopyLine();
	ResponseAnalysis();
	while (m_nRecvByte != 0)
	{
		CopyLine();
		ResponseAnalysis();
	}
}

void RequestHandle::SetDataPort(void)
{
	char port1[4] = {0,};
	char port2[4] = {0,};
	m_pcCopyParse = m_cCopyBuf;
	for (int i = 0; i < 4; ++i, ++m_pcCopyParse)
	{
		m_pcCopyParse = strchr(m_pcCopyParse, ',');
	}
	for (int i = 0; *m_pcCopyParse != ','; ++m_pcCopyParse, ++i)
	{
		port1[i] = *m_pcCopyParse;
	}
	++m_pcCopyParse;
	for (int i = 0; *m_pcCopyParse != ')'; ++m_pcCopyParse, ++i)
	{
		port2[i] = *m_pcCopyParse;
	}
	unsigned short p1 = atoi(port1);
	unsigned short p2 = atoi(port2);
	m_DataPort = p1 * 256 + p2;
}

void RequestHandle::ResponsePWD(void)
{
	m_pcCopyParse += 5;
	int i;
	for (i = 0; *m_pcCopyParse != '"'; ++m_pcCopyParse, ++i)
	{
		m_cSendBuf[i] = *m_pcCopyParse;
	}
	if (*m_pcCopyParse != '/' && strlen(m_cCopyBuf) != 1)
	{
		m_cServPath[i] = '/';
	}
}

void RequestHandle::ResponsePASV(void)
{
	SetDataPort();
	send(m_nConn, "LIST\r\n", 6, 0);
}

void RequestHandle::CreateDataConn(void)
{
	memset(&m_kSockAddr, 0, sizeof(m_kSockAddr));
	m_nDataConn = socket(AF_INET, SOCK_STREAM, 0);
	if (m_nDataConn == INVALID_SOCKET)
	{
		AfxMessageBox("socket() error");
	}
	m_kSockAddr.sin_family = AF_INET;
	m_kSockAddr.sin_addr.s_addr = inet_addr(m_cIP);
	m_kSockAddr.sin_port = htons(m_DataPort);
	
	if (connect(m_nDataConn, (SOCKADDR*)&m_kSockAddr, sizeof(m_kSockAddr)) == SOCKET_ERROR)
	{
		AfxMessageBox("connect() error");
	}
}

void RequestHandle::PutItemList(void)
{
	int listnum = 0;
	int filenum = 0;
	char *pcCpy;
	char tempBuf[128] = {0,};

	m_pkDirList->DeleteAllItems();
	m_pkFileList->DeleteAllItems();
	memset(m_cNameBuf, 0, CustomBuf::BIGBUF + 1);
	delete m_pkDataRecv;
	m_pkDataRecv = new RecvLine(m_nDataConn);

	while (1)
	{
		m_pkDataRecv->CopyLine();
		if (m_pkDataRecv->GetClosed())
		{
			break;
		}
		pcCpy = m_pkDataRecv->GetCopyBuf();
		if (*pcCpy == 'd')
		{

			pcCpy = ToWhiteSpace(pcCpy);
			pcCpy = PassWhiteSpace(pcCpy);
			pcCpy = DirectorySave(pcCpy);
			SaveName(pcCpy);
			m_pkDirList->InsertItem(listnum, m_cNameBuf);
			++listnum;
		} 
		else if (*pcCpy == '-')
		{

			pcCpy = ToWhiteSpace(pcCpy);
			pcCpy = PassWhiteSpace(pcCpy);
			pcCpy = FileSave(pcCpy);

			SaveName(pcCpy);
			m_pkFileList->InsertItem(filenum, m_cNameBuf);
			m_pkFileList->SetItemText(filenum, 1, m_cSizeBuf);
			++filenum;
		}
	}

	closesocket(m_nDataConn);
}

char *RequestHandle::DirectorySave(char *p)
{
	int count;
	if (*p == 'r' || *p == 's')
	{
		count = 4;
	}
	else
	{
		count = 7;
	}

	for (int i = 0; i < count; ++i)
	{
		p = ToWhiteSpace(p);
		p = PassWhiteSpace(p);
	}

	return p;
}


char *RequestHandle::FileSave(char *p)
{
	int count;
	if (*p == 'r' || *p == 's')				// Android
	{
		count = 3;
	}
	else									// Linux and Filezilla on Windows
	{
		count = 4;
	}

	for (int i = 0; i < count - 1; ++i)
	{
		p = ToWhiteSpace(p);
		p = PassWhiteSpace(p);
	}
	m_nFileSize = atoi(p);
	itoa(m_nFileSize, m_cSizeBuf, 10);
	for (int i = 0; i < count; ++i)
	{
		p = ToWhiteSpace(p);
		p = PassWhiteSpace(p);
	}

	return p;
}

void RequestHandle::SaveName(char *p)
{
	int i;
	for (i = 0; *p != '\r'; ++i, ++p)
	{
		m_cNameBuf[i] = *p;
	}
	m_cNameBuf[i] = 0;
}

char* RequestHandle::ToWhiteSpace(char *p)
{
	for (; *p != 32 && *p != '\t'; ++p);
	return p;
}

char* RequestHandle::PassWhiteSpace(char *p)
{
	for (; *p == 32 || *p == '\t'; ++p);
	return p;
}

void RequestHandle::SetIP(char *ip)
{
	strncpy_s(m_cIP, CustomBuf::SYNBUFSIZE, ip, 16);
}